<template>
  <div class="clearfix" style="margin-left: 5px">
    <a-upload
      :listType="listType"
      :multiple="multiple"
      v-model:fileList="uploadFileList"
      :disabled="disabled"
      :openFileDialogOnClick="openFileDialogOnClick"
      @change="handleUploadChange"
    >
      <div v-if="uploadVisible" @click="handleClickUpload">
        <div v-if="listType == 'picture-card'">
          <LoadingOutlined v-if="loading" />
          <UploadOutlined v-else />
          <div class="ant-upload-text">{{ text }}</div>
        </div>
        <a-button v-if="listType == 'picture'" :disabled="disabled">
          <UploadOutlined />
          {{ text }}
        </a-button>
      </div>
      <template #itemRender="{ file, actions }">
        <SelectImageMaterialItem v-if="file.type === MaterialType.IMAGE.type" @remove="actions.remove" :file="file" />
        <SelectVoiceMaterialItem v-if="file.type === MaterialType.VOICE.type" @remove="actions.remove" :file="file" />
      </template>
    </a-upload>

    <MySelectMaterialModal
      @register="registerSelectMaterialModal"
      :materialType="materialType"
      :selectCount="fileMax"
      @select-change="handleSelectChange"
    />
  </div>
</template>
<script lang="ts">
  import { defineComponent, PropType, ref, unref, reactive, watchEffect, computed, watch } from "vue"
  import { LoadingOutlined, UploadOutlined } from "@ant-design/icons-vue"
  import { useRuleFormItem } from "/@/hooks/component/useFormItem"
  import { propTypes } from "/@/utils/propTypes"
  import { useAttrs } from "/@/hooks/core/useAttrs"
  import { useModal } from "/@/components/Modal"
  import { useMessage } from "/@/hooks/web/useMessage"
  import { getFileAccessHttpUrl, getRandom } from "/@/utils/common/compUtils"
  import { useGlobSetting } from "/@/hooks/setting"
  import { isArray, isString } from "/@/utils/is"
  import MySelectMaterialModal from "./MySelectMaterialModal.vue"
  import SelectImageMaterialItem from "./components/SelectImageMaterialItem.vue"
  import SelectVoiceMaterialItem from "./components/SelectVoiceMaterialItem.vue"
  import { listMaterial } from "/@/api/infra/material"
  import { MaterialType } from "./material.data"
  import { deleteGroup } from "/@/api/infra/material"

  const globSetting = useGlobSetting()

  const { createMessage, createErrorModal } = useMessage()

  interface MaterialItem {
    id: string
    url: string
    name: string
    /**
     * @see MaterialType
     */
    type: string
  }

  export default defineComponent({
    name: "MySelectMaterial",
    components: {
      LoadingOutlined,
      UploadOutlined,
      MySelectMaterialModal,
      SelectImageMaterialItem,
      SelectVoiceMaterialItem,
    },
    inheritAttrs: false,
    props: {
      //绑定值
      value: propTypes.oneOfType([propTypes.string, propTypes.array]).def(""),
      //按钮文本
      listType: {
        type: String,
        required: false,
        default: "picture",
      },
      //按钮文本
      text: {
        type: String,
        required: false,
        default: "选择素材",
      },

      /**
       * 选择的媒体类型, 不填, 在选择媒体文件的弹窗中会展示所有媒体类型文件
       * @see MaterialType
       */
      materialType: {
        type: String,
        required: false,
      },

      //是否禁用
      disabled: {
        type: Boolean,
        required: false,
        default: false,
      },
      //选择的文件数量
      fileMax: {
        type: Number,
        required: false,
        default: 1,
      },
      // 表单字段名
      fieldName: {
        type: String,
        required: false,
        default: "id",
      },
    },
    emits: ["options-change", "change", "update:value"],
    setup(props, { emit, refs }) {
      const emitData = ref<any[]>([])
      const attrs = useAttrs()
      const [registerSelectMaterialModal, { openModal: openSelectMaterialModal }] = useModal()
      const [state, setState] = useRuleFormItem(props, "value", "change", emitData)
      //获取文件名
      const getFileName = (path) => {
        if (path.lastIndexOf("\\") >= 0) {
          let reg = new RegExp("\\\\", "g")
          path = path.replace(reg, "/")
        }
        return path.substring(path.lastIndexOf("/") + 1)
      }
      //token

      const openFileDialogOnClick = ref(false)
      //上传状态
      const loading = ref<boolean>(false)
      //是否是初始化加载
      const initTag = ref<boolean>(true)
      //文件列表
      let uploadFileList = ref<any[]>([])

      //计算是否开启多图上传
      const multiple = computed(() => {
        return props["fileMax"] > 1
      })

      //计算是否可以继续上传
      const uploadVisible = computed(() => {
        return uploadFileList.value.length < props["fileMax"]
      })

      /**
       * 监听value变化
       */
      watchEffect(async () => {
        console.log("props", props)
        let val = props.value
        if (val instanceof Array) {
          val = val.join(",")
        }
        if (initTag.value == true && val && val.length > 0) {
          const searchParams = {}
          const key = props.fieldName === "id" ? "ids" : `${props.fieldName}s`
          searchParams[key] = val
          const materialList = await listMaterial(searchParams)
          console.log("materialList", materialList)
          initFileList(materialList)
        }
      })

      /**
       * 初始化文件列表
       */
      function initFileList(materialList) {
        if (!materialList || materialList.length == 0) {
          uploadFileList.value = []
          return
        }
        let files: any[] = []
        let arr: MaterialItem[] = isArray(materialList) ? materialList : JSON.parse(materialList)
        arr.forEach((item) => {
          let url = getFileAccessHttpUrl(item.url)
          files.push({
            uid: getRandom(10),
            name: getFileName(item.name),
            type: item.type,
            id: item.id,
            status: "done",
            url: url,
            response: {
              status: "history",
              message: "success",
            },
          })
        })
        uploadFileList.value = files
      }

      const handleClickUpload = () => {
        openSelectMaterialModal(true, {})
      }

      const handleSelectChange = (rows) => {
        console.log("rows", rows)
        if (rows.length === 0) {
          return
        }
        // 排除已经选择的
        const materialIds = uploadFileList.value.map((e) => e.id)
        const filterRows = rows.filter((e) => !materialIds.includes(e.id))
        uploadFileList.value.forEach((e) => filterRows.push(e))
        initFileList(JSON.stringify(filterRows))
        handleEmitData()
      }

      const handleUploadChange = () => {
        handleEmitData()
      }

      const handleEmitData = () => {
        const data: string[] = uploadFileList.value.map((e) => e[props.fieldName])
        if (isArray(props.value)) {
          setState(data)
          emit("change", data)
        } else if (isString(props.value)) {
          const dataStr = data.join(",")
          setState(dataStr)
          emit("change", dataStr)
        } else {
          console.log("不支持的value类型, 只支持数组和字符串, value", props.value)
        }
      }

      return {
        MaterialType,
        state,
        attrs,
        uploadFileList,
        multiple,
        loading,
        openFileDialogOnClick,
        uploadVisible,
        handleClickUpload,
        registerSelectMaterialModal,
        handleSelectChange,
        handleUploadChange,
      }
    },
  })
</script>
<style scoped>
  .ant-upload-select-picture-card i {
    font-size: 32px;
    color: #999;
  }

  .ant-upload-select-picture-card .ant-upload-text {
    margin-top: 0px;
    color: #666;
  }
</style>
